package code.google.jcontainer.annotation;

import code.google.jcontainer.resolver.AnnotationResolver;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Used to declare the resolveClass and when for managed annotation.
 * take a look at {@link code.google.jcontainer.support.log.Log} or {@link code.google.jcontainer.support.intercept.Intercept} for examples.
 *
 * And, can be used to define resolveClass&when for third party annotation.
 * for example, we'd like to resolve the JDK embedded annotation {@link javax.jws.WebMethod}
 * \@Container(
 *        name = "SimpleContainer3",
 *        componentType = SimpleBean.class, // the annotated class want to be managed by this container
 *        resolveAnnotations = {
 *                \@Resolve(
 *                        annotationClass = WebMethod.class,
 *                        resolverClass = WebMethodAnnotationResolver.class,
 *                        when = {Resolve.WHEN.AFTER_CONSTRUCT})
 *        }
 * )

 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 */
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Resolve {

    /**
     * this field only need to be specified the 3party annotation by using {@link Container#resolveAnnotations()}
     * When used to annotate an annotation, don't need to specify annotationClass.
     */
    Class<? extends Annotation> annotationClass() default Annotation.class;

    /**
     * Specify Annotation Resolver class for the annotated annotation
     * the resolveClass should implement the corresponding {@link code.google.jcontainer.resolver.ClassAnnotationResolver} and {@link code.google.jcontainer.resolver.MethodAnnotationResolver} and {@link code.google.jcontainer.resolver.FieldAnnotationResolver}}  
     */
    Class<? extends AnnotationResolver> resolverClass();

    /**
     * Specify when to resolve the annotated annotation.
     * {@link code.google.jcontainer.annotation.Resolve.WHEN} is a public inner enum class to define the phase of resolving the annotation
     */
    WHEN[] when();

    /**
     * A enum class to define when to resolve annotation
     */
    public static enum WHEN {
        /**
         * Resolve the annotated annotation before constructing component
         */
        BEFORE_CONSTRUCT(1),
        /**
         * Resolve the annotated annotation after constructing component
         */
        AFTER_CONSTRUCT(2),
        /**
         * Resolve the annotated annotation before invoking a method of component
         */
        BEFORE_METHOD(4),
        /**
         * Resolve the annotated annotation after invoking a method of component
         */
        AFTER_METHOD(8);

        private int intValue;

        WHEN(int intValue) {
            this.intValue = intValue;
        }

        public int getIntValue(){
            return intValue;
        }

        public boolean equals(WHEN when) {
            return this.intValue == when.getIntValue();
        }
    }
}